package com.ysh.smartplatform.service.impl;

import com.ysh.smartplatform.cache.SceneCache;
import com.ysh.smartplatform.constans.ResultCode;
import com.ysh.smartplatform.event.CategoryChangeEvent;
import com.ysh.smartplatform.event.SceneEvent;
import com.ysh.smartplatform.exceptions.AddDataException;
import com.ysh.smartplatform.exceptions.FindDataException;
import com.ysh.smartplatform.mapper.SceneMapper;
import com.ysh.smartplatform.pojo.BaseUser;
import com.ysh.smartplatform.pojo.Scene;
import com.ysh.smartplatform.pojo.SysUserInfo;
import com.ysh.smartplatform.service.SceneService;
import com.ysh.smartplatform.utils.SecurityUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 袁胜虎 on 2022/9/8 11:54
 */
@Service
@Transactional
public class SceneServiceImpl implements SceneService {
    private ApplicationContext context;

    @Autowired
    public void setContext(ApplicationContext context) {
        this.context = context;
    }

    private SceneCache sceneCache;

    @Autowired
    public void setSceneCache(SceneCache sceneCache) {
        this.sceneCache = sceneCache;
    }

    private SceneMapper sceneMapper;

    @Autowired
    public void setSceneMapper(SceneMapper sceneMapper) {
        this.sceneMapper = sceneMapper;
    }

    @Override
    public void addScene(Scene scene) {
        //将数据插入到数据库就行, 我们的名字可以重复
        //场景是属于用户的,和用户是一对多的关系,创建者就是当前登录的用户
        BaseUser loginUser = SecurityUtils.getLoginUser();
        scene.setCreateBy(loginUser.getuId());
        //添加数据
        sceneMapper.insertSelective(scene);
        //更新缓存,写什么?发布事件,交给缓存自己更新
        context.publishEvent(new SceneEvent());
    }

    @Override
    public void updateScene(Scene scene) {

        sceneMapper.updateByPrimaryKeySelective(scene);
    }

    @Override
    public Scene getSceneById(Long id) {
        //用户只能查询属于自己的场景,所以当前的id必须是自己的场景的id
        BaseUser loginUser = SecurityUtils.getLoginUser();
        //获取到用户的所有的场景
        List<Scene> sceneList = sceneCache.get(loginUser.getuId());
        Assert.notNull(sceneList,()->{
            throw  new AddDataException("当前场景不存在", ResultCode.DATA_NOT_EXIST);
        });

        //获取当前id对应的场景数据
        List<Scene> list = sceneList.stream().filter(scene -> scene.getSceneId().equals(id)).collect(Collectors.toList());
        //如果有这个场景,长度就一定1
        Assert.isTrue(list.size() == 1,()->{
            throw  new FindDataException("当前场景不存在",ResultCode.DATA_NOT_EXIST);
        });
        return list.get(0);
    }

    @Override
    public List<Scene> getAllScenesByUser() {
        //用户可能在短时间内查看了多次,在用户比较多的情况下,这个操作会执行很多次,那么就带来了一个问题,大量的查询数据库
        //我们会用缓存,但是和我们的分类的缓存不一样,分类缓存是针对所有用户的,但是场景是真针对每个用户的,所以这个的需要设置有效期
        //有什么技术可以这种临时保存数据,设置有效期,并且能在有效期到了之后删除数据
       BaseUser loginUser = SecurityUtils.getLoginUser();
        List<Scene> sceneList = sceneCache.get(loginUser.getuId());
        return sceneList;
    }

    @Override
    public void deleteScenes(List<Long> ids) {
        //理论上删除只能删除用户自己下面的场景

    }

    @Override
    public void deleteBySceneName(String sceneName) {
        Assert.notNull(sceneName,()->{
            throw  new AddDataException("没有此类场景",ResultCode.DATA_NOT_EXIST);
        });
        sceneMapper.deleteBySceneName(sceneName);
        //更新缓存,写什么?发布事件,交给缓存自己更新
        context.publishEvent(new SceneEvent());
    }
}
